Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / RNode_Firmware.git / files / RNode_Firmware.ino

Displaying Raw • Download


RNode_Firmware.ino 3deab29845fbfa978ce8b488505b05f6be8cf4e4 (3deab298) Text, 11.41 KB

Tff7b72#Tff7b72include T8b949e<SPI.h>
Tff7b72#Tff7b72include T8b949e<LoRa.h>
Tff7b72#Tff7b72include T8b949e"Config.h"
Tff7b72#Tff7b72include T8b949e"Framing.h"
Tff7b72#Tff7b72include T8b949e"Utilities.cpp"

Tff7b72void Tffa657setupTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Seed the PRNG
Td2a8ffrandomSeedTb4b4b4(Td2a8ffanalogReadTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4)Tb4b4b4;

T8b949e// Initialise serial communication
Td2a8ffSerialTb4b4b4.Td2a8ffbeginTb4b4b4(Te6edf3serial_baudrateTb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Tff7b72!Td2a8ffSerialTb4b4b4)Tb4b4b4;

T8b949e// Configure input and output pins
Td2a8ffpinModeTb4b4b4(Te6edf3pin_led_rxTb4b4b4, Tff7b72OUTPUTTb4b4b4)Tb4b4b4;
Td2a8ffpinModeTb4b4b4(Te6edf3pin_led_txTb4b4b4, Tff7b72OUTPUTTb4b4b4)Tb4b4b4;

T8b949e// Set up buffers
Te6edf3memsetTb4b4b4(Te6edf3pbufTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3pbufTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3memsetTb4b4b4(Te6edf3sbufTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3sbufTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3memsetTb4b4b4(Te6edf3cbufTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3cbufTb4b4b4)Tb4b4b4)Tb4b4b4;

T8b949e// Set chip select, reset and interrupt
T8b949e// pins for the LoRa module
Te6edf3LoRaTb4b4b4.Te6edf3setPinsTb4b4b4(Te6edf3pin_csTb4b4b4, Te6edf3pin_resetTb4b4b4, Te6edf3pin_dioTb4b4b4)Tb4b4b4;

T8b949e// Validate board health, EEPROM and config
Te6edf3validateStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tff7b72bool Td2a8ffstartRadioTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3update_radio_lockTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3radio_onlineTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3radio_locked Tff7b72&Tff7b72& Te6edf3hw_readyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3LoRaTb4b4b4.Td2a8ffbeginTb4b4b4(Te6edf3lora_freqTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// The radio could not be started.
T8b949e// Indicate this failure over both the
T8b949e// serial port and with the onboard LEDs
Te6edf3kiss_indicate_errorTb4b4b4(Te6edf3ERROR_INITRADIOTb4b4b4)Tb4b4b4;
Te6edf3led_indicate_errorTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3radio_online Tff7b72= Tff7b72trueTb4b4b4;

Te6edf3setTXPowerTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3setBandwidthTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3setSpreadingFactorTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3setCodingRateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3getFrequencyTb4b4b4(Tb4b4b4)Tb4b4b4;

Te6edf3LoRaTb4b4b4.Te6edf3enableCrcTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3LoRaTb4b4b4.Td2a8ffonReceiveTb4b4b4(Te6edf3receiveCallbackTb4b4b4)Tb4b4b4;

Te6edf3LoRaTb4b4b4.Te6edf3receiveTb4b4b4(Tb4b4b4)Tb4b4b4;

T8b949e// Flash an info pattern to indicate
T8b949e// that the radio is now on
Te6edf3led_indicate_infoTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Flash a warning pattern to indicate
T8b949e// that the radio was locked, and thus
T8b949e// not started
Te6edf3led_indicate_warningTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// If radio is already on, we silently
T8b949e// ignore the request.
Tb4b4b4}
Tb4b4b4}

Tff7b72void Td2a8ffstopRadioTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3LoRaTb4b4b4.Td2a8ffendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3radio_online Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}

Tff7b72void Td2a8ffupdate_radio_lockTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3lora_freq Tff7b72!Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3lora_bw Tff7b72!Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3lora_txp Tff7b72!Tff7b72= T79c0ff0xFF Tff7b72&Tff7b72& Te6edf3lora_sf Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3radio_locked Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3radio_locked Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72void Td2a8ffreceiveCallbackTb4b4b4(Tff7b72int Te6edf3packet_sizeTb4b4b4) Tb4b4b4{
Tff7b72uint8_t Te6edf3header Tff7b72= Te6edf3LoRaTb4b4b4.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3packet_sizeTff7b72-Tff7b72-Tb4b4b4;
Tff7b72uint8_t Te6edf3sequence Tff7b72= Te6edf3packetSequenceTb4b4b4(Te6edf3headerTb4b4b4)Tb4b4b4;
Tff7b72bool Td2a8ffready Tff7b72= Tff7b72falseTb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3isSplitPacketTb4b4b4(Te6edf3headerTb4b4b4) Tff7b72&Tff7b72& Te6edf3seq Tff7b72=Tff7b72= Te6edf3SEQ_UNSETTb4b4b4) Tb4b4b4{
T8b949e// This is the first part of a split
T8b949e// packet, so we set the seq variable
T8b949e// and add the data to the buffer
Te6edf3read_len Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3seq Tff7b72= Te6edf3sequenceTb4b4b4;
Te6edf3last_rssi Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3isSplitPacketTb4b4b4(Te6edf3headerTb4b4b4) Tff7b72&Tff7b72& Te6edf3seq Tff7b72=Tff7b72= Te6edf3sequenceTb4b4b4) Tb4b4b4{
T8b949e// This is the second part of a split
T8b949e// packet, so we add it to the buffer
T8b949e// and set the ready flag.
Te6edf3last_rssi Tff7b72= Tb4b4b4(Te6edf3last_rssiTff7b72+Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72/T79c0ff2Tb4b4b4;
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
Te6edf3seq Tff7b72= Te6edf3SEQ_UNSETTb4b4b4;
Td2a8ffready Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3isSplitPacketTb4b4b4(Te6edf3headerTb4b4b4) Tff7b72&Tff7b72& Te6edf3seq Tff7b72!Tff7b72= Te6edf3sequenceTb4b4b4) Tb4b4b4{
T8b949e// This split packet does not carry the
T8b949e// same sequence id, so we must assume
T8b949e// that we are seeing the first part of
T8b949e// a new split packet.
Te6edf3read_len Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3seq Tff7b72= Te6edf3sequenceTb4b4b4;
Te6edf3last_rssi Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3isSplitPacketTb4b4b4(Te6edf3headerTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// This is not a split packet, so we
T8b949e// just read it and set the ready
T8b949e// flag to true.

Tff7b72if Tb4b4b4(Te6edf3seq Tff7b72!Tff7b72= Te6edf3SEQ_UNSETTb4b4b4) Tb4b4b4{
T8b949e// If we already had part of a split
T8b949e// packet in the buffer, we clear it.
Te6edf3read_len Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3seq Tff7b72= Te6edf3SEQ_UNSETTb4b4b4;
Tb4b4b4}

Te6edf3last_rssi Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
Td2a8ffready Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Td2a8ffreadyTb4b4b4) Tb4b4b4{
T8b949e// We first signal the RSSI of the
T8b949e// recieved packet to the host.
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3FENDTb4b4b4)Tb4b4b4;
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3CMD_STAT_RSSITb4b4b4)Tb4b4b4;
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Tb4b4b4(Tff7b72uint8_tTb4b4b4)Tb4b4b4(Te6edf3last_rssiTff7b72-Te6edf3rssi_offsetTb4b4b4)Tb4b4b4)Tb4b4b4;

T8b949e// And then write the entire packet
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3FENDTb4b4b4)Tb4b4b4;
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3CMD_DATATb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3read_lenTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72uint8_t Tff7b72byte Tff7b72= Te6edf3pbufTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72byte Tff7b72=Tff7b72= Te6edf3FENDTb4b4b4) Tb4b4b4{ Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3FESCTb4b4b4)Tb4b4b4; Tff7b72byte Tff7b72= Te6edf3TFENDTb4b4b4; Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72byte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{ Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3FESCTb4b4b4)Tb4b4b4; Tff7b72byte Tff7b72= Te6edf3TFESCTb4b4b4; Tb4b4b4}
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Tff7b72byteTb4b4b4)Tb4b4b4;
Tb4b4b4}
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3FENDTb4b4b4)Tb4b4b4;
Te6edf3read_len Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72void Td2a8fftransmitTb4b4b4(Tffa657size_t Td2a8ffsizeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3radio_onlineTb4b4b4) Tb4b4b4{
Te6edf3led_tx_onTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657size_t Te6edf3written Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72uint8_t Te6edf3header Tff7b72= Td2a8ffrandomTb4b4b4(T79c0ff256Tb4b4b4) Tff7b72& T79c0ff0xF0Tb4b4b4;

Tff7b72if Tb4b4b4(Td2a8ffsize Tff7b72> Te6edf3SINGLE_MTU Tff7b72- Te6edf3HEADER_LTb4b4b4) Tb4b4b4{
Te6edf3header Tff7b72= Te6edf3header Tff7b72| Te6edf3FLAG_SPLITTb4b4b4;
Tb4b4b4}

Te6edf3LoRaTb4b4b4.Td2a8ffbeginPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3LoRaTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3headerTb4b4b4)Tb4b4b4; Te6edf3writtenTff7b72+Tff7b72+Tb4b4b4;

Tff7b72for Tb4b4b4(Tffa657size_t Te6edf3iTb4b4b4; Te6edf3i Tff7b72< Td2a8ffsizeTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3LoRaTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3sbufTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3writtenTff7b72+Tff7b72+Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3written Tff7b72=Tff7b72= T79c0ff255Tb4b4b4) Tb4b4b4{
Te6edf3LoRaTb4b4b4.Td2a8ffendPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3LoRaTb4b4b4.Td2a8ffbeginPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3LoRaTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3headerTb4b4b4)Tb4b4b4;
Te6edf3written Tff7b72= T79c0ff1Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Te6edf3LoRaTb4b4b4.Td2a8ffendPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3led_tx_offTb4b4b4(Tb4b4b4)Tb4b4b4;

Te6edf3LoRaTb4b4b4.Te6edf3receiveTb4b4b4(Tb4b4b4)Tb4b4b4;

Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3kiss_indicate_errorTb4b4b4(Te6edf3ERROR_TXFAILEDTb4b4b4)Tb4b4b4;
Te6edf3led_indicate_errorTb4b4b4(T79c0ff5Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3FLOW_CONTROL_ENABLEDTb4b4b4)
Te6edf3kiss_indicate_readyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tff7b72void Td2a8ffserialCallbackTb4b4b4(Tff7b72uint8_t Te6edf3sbyteTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3IN_FRAME Tff7b72&Tff7b72& Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FEND Tff7b72&Tff7b72& Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_DATATb4b4b4) Tb4b4b4{
Te6edf3IN_FRAME Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3outbound_ready Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FENDTb4b4b4) Tb4b4b4{
Te6edf3IN_FRAME Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3command Tff7b72= Te6edf3CMD_UNKNOWNTb4b4b4;
Te6edf3frame_len Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3IN_FRAME Tff7b72&Tff7b72& Te6edf3frame_len Tff7b72< Te6edf3MTUTb4b4b4) Tb4b4b4{
T8b949e// Have a look at the command byte first
Tff7b72if Tb4b4b4(Te6edf3frame_len Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3command Tff7b72= Te6edf3sbyteTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_DATATb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{
Te6edf3ESCAPE Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ESCAPETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFENDTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FENDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFESCTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FESCTb4b4b4;
Te6edf3ESCAPE Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3sbufTb4b4b4[Te6edf3frame_lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3sbyteTb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_FREQUENCYTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{
Te6edf3ESCAPE Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ESCAPETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFENDTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FENDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFESCTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FESCTb4b4b4;
Te6edf3ESCAPE Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3cbufTb4b4b4[Te6edf3frame_lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3sbyteTb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3frame_len Tff7b72=Tff7b72= T79c0ff4Tb4b4b4) Tb4b4b4{
Tff7b72uint32_t Te6edf3freq Tff7b72= Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff24 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72<Tff7b72< T79c0ff16 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3freq Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_frequencyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3lora_freq Tff7b72= Te6edf3freqTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setFrequencyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_frequencyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_BANDWIDTHTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{
Te6edf3ESCAPE Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ESCAPETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFENDTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FENDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFESCTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FESCTb4b4b4;
Te6edf3ESCAPE Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3cbufTb4b4b4[Te6edf3frame_lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3sbyteTb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3frame_len Tff7b72=Tff7b72= T79c0ff4Tb4b4b4) Tb4b4b4{
Tff7b72uint32_t Te6edf3bw Tff7b72= Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff24 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72<Tff7b72< T79c0ff16 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3bw Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_bandwidthTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3lora_bw Tff7b72= Te6edf3bwTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setBandwidthTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_bandwidthTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_TXPOWERTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_txpowerTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72int Te6edf3txp Tff7b72= Te6edf3sbyteTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3txp Tff7b72> T79c0ff17Tb4b4b4) Te6edf3txp Tff7b72= T79c0ff17Tb4b4b4;

Te6edf3lora_txp Tff7b72= Te6edf3txpTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setTXPowerTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_txpowerTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_SFTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_spreadingfactorTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72int Te6edf3sf Tff7b72= Te6edf3sbyteTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sf Tff7b72< T79c0ff7Tb4b4b4) Te6edf3sf Tff7b72= T79c0ff7Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sf Tff7b72> T79c0ff12Tb4b4b4) Te6edf3sf Tff7b72= T79c0ff12Tb4b4b4;

Te6edf3lora_sf Tff7b72= Te6edf3sfTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setSpreadingFactorTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_spreadingfactorTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_CRTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_codingrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72int Te6edf3cr Tff7b72= Te6edf3sbyteTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cr Tff7b72< T79c0ff5Tb4b4b4) Te6edf3cr Tff7b72= T79c0ff5Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cr Tff7b72> T79c0ff8Tb4b4b4) Te6edf3cr Tff7b72= T79c0ff8Tb4b4b4;

Te6edf3lora_cr Tff7b72= Te6edf3crTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setCodingRateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_codingrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_RADIO_STATETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_radiostateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0x00Tb4b4b4) Tb4b4b4{
Te6edf3stopRadioTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_radiostateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0x01Tb4b4b4) Tb4b4b4{
Te6edf3startRadioTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_radiostateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_STAT_RXTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_stat_rxTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_STAT_TXTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_stat_txTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_STAT_RSSITb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_stat_rssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_RADIO_LOCKTb4b4b4) Tb4b4b4{
Te6edf3update_radio_lockTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_radio_lockTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_BLINKTb4b4b4) Tb4b4b4{
Te6edf3led_indicate_infoTb4b4b4(Te6edf3sbyteTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_RANDOMTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_randomTb4b4b4(Te6edf3getRandomTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_DETECTTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3DETECT_REQTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_detectTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_UNLOCK_ROMTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3ROM_UNLOCK_BYTETb4b4b4) Tb4b4b4{
Te6edf3unlock_romTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_ROM_READTb4b4b4) Tb4b4b4{
Te6edf3kiss_dump_eepromTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_ROM_WRITETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{
Te6edf3ESCAPE Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ESCAPETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFENDTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FENDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFESCTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FESCTb4b4b4;
Te6edf3ESCAPE Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3cbufTb4b4b4[Te6edf3frame_lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3sbyteTb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3frame_len Tff7b72=Tff7b72= T79c0ff2Tb4b4b4) Tb4b4b4{
Te6edf3eeprom_writeTb4b4b4(Te6edf3cbufTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3cbufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_FW_VERSIONTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_versionTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_CONF_SAVETb4b4b4) Tb4b4b4{
Te6edf3eeprom_conf_saveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_CONF_DELETETb4b4b4) Tb4b4b4{
Te6edf3eeprom_conf_deleteTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72void Td2a8ffupdateModemStatusTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72uint8_t Te6edf3status Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3modemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3last_status_update Tff7b72= Td2a8ffmillisTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3status Tff7b72& Te6edf3SIG_DETECT Tff7b72=Tff7b72= T79c0ff0x01Tb4b4b4) Tb4b4b4{ Te6edf3stat_signal_detected Tff7b72= Tff7b72trueTb4b4b4; Tb4b4b4} Tff7b72else Tb4b4b4{ Te6edf3stat_signal_detected Tff7b72= Tff7b72falseTb4b4b4; Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3status Tff7b72& Te6edf3SIG_SYNCED Tff7b72=Tff7b72= T79c0ff0x01Tb4b4b4) Tb4b4b4{ Te6edf3stat_signal_synced Tff7b72= Tff7b72trueTb4b4b4; Tb4b4b4} Tff7b72else Tb4b4b4{ Te6edf3stat_signal_synced Tff7b72= Tff7b72falseTb4b4b4; Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3status Tff7b72& Te6edf3RX_ONGOING Tff7b72=Tff7b72= T79c0ff0x01Tb4b4b4) Tb4b4b4{ Te6edf3stat_rx_ongoing Tff7b72= Tff7b72trueTb4b4b4; Tb4b4b4} Tff7b72else Tb4b4b4{ Te6edf3stat_rx_ongoing Tff7b72= Tff7b72falseTb4b4b4; Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3stat_signal_detected Tff7b72|Tff7b72| Te6edf3stat_signal_synced Tff7b72|Tff7b72| Te6edf3stat_rx_ongoingTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dcd_count Tff7b72< Te6edf3dcd_thresholdTb4b4b4) Tb4b4b4{
Te6edf3dcd_countTff7b72+Tff7b72+Tb4b4b4;
Te6edf3dcd Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3dcd Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3dcd_led Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dcd_count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3dcd_countTff7b72-Tff7b72-Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3dcd_led Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3dcd Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3dcd_ledTb4b4b4) Tb4b4b4{
Te6edf3led_rx_onTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3led_rx_offTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72void Td2a8ffcheckModemStatusTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Td2a8ffmillisTb4b4b4(Tb4b4b4)Tff7b72-Te6edf3last_status_update Tff7b72>Tff7b72= Te6edf3status_interval_msTb4b4b4) Tb4b4b4{
Te6edf3updateModemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72void Td2a8ffvalidateStatusTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eeprom_lock_setTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eeprom_product_validTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3eeprom_model_validTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3eeprom_hwrev_validTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eeprom_checksum_validTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3hw_ready Tff7b72= Tff7b72trueTb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3eeprom_have_confTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3eeprom_conf_loadTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3op_mode Tff7b72= Te6edf3MODE_TNCTb4b4b4;
Te6edf3startRadioTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3hw_ready Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3hw_ready Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72void Tffa657loopTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3radio_onlineTb4b4b4) Tb4b4b4{
Te6edf3checkModemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3outbound_readyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3dcd_waitingTb4b4b4) Te6edf3updateModemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3dcd Tff7b72&Tff7b72& Tff7b72!Te6edf3dcd_ledTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dcd_waitingTb4b4b4) Td2a8ffdelayTb4b4b4(Te6edf3lora_rx_turnaround_msTb4b4b4)Tb4b4b4;
Te6edf3updateModemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3dcdTb4b4b4) Tb4b4b4{
Te6edf3outbound_ready Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3dcd_waiting Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3frame_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3dcd_waiting Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3hw_readyTb4b4b4) Tb4b4b4{
Te6edf3led_indicate_standbyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3led_indicate_not_readyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stopRadioTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72if Tb4b4b4(Td2a8ffSerialTb4b4b4.Td2a8ffavailableTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72char Te6edf3sbyte Tff7b72= Td2a8ffSerialTb4b4b4.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3serialCallbackTb4b4b4(Te6edf3sbyteTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────